#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
 
 
void sys_err(const char *str)
{
        perror(str);
        exit(1);
}
 
void catch_child(int signo)
{
	pid_t wpid;
	int status;
	// 防止僵尸进程出现，所以循环处理
	// 如果不循环，同时收到多个相同信号，默认会屏蔽，只会执行一次，而且每次收到信号后只执行一次wait函数，
	// 当多个子进程同时结束，也只会回收一个子进程，所以当收到子进程信号时，循环执行wait，等待同时结束的的所有进程.
	// while ((wpid = wait(NULL)) != -1){
	while ((wpid = waitpid(-1, &status, 0)) != -1){
		if (WIFEXITED(status))
		printf("-------catch child id %d, ret = %d\n", wpid, WEXITSTATUS(status));
	}
	return;
}
int main(int argc, char *argv[])
{
	pid_t pid;
// 阻塞
	int i;
	for (i = 0; i < 15; i++){
		if ((pid = fork()) == 0)
			break;
	}
	if (15 == i){
		// 父进程
		// 注册信号
		struct sigaction act;
		act.sa_handler = catch_child;	// 设置回调函数
		act.sa_flags = 0;		// 设置捕捉函数执行期间屏蔽字
		sigemptyset(&act.sa_mask);	// 设置默认属性，本信号自动屏蔽
		sigaction(SIGCHLD, &act, NULL);	// 注册信号捕捉函数
// 解除阻塞
		printf("I'm parent, pid = %d\n", getpid());
		while(1);
	}else {
		// 子进程
		printf("I'm child, pid = %d\n", getpid());
		return i;
	}
	
        return 0;
}
